#include "vsf_hal.h"
#include "sthal.h"

static UART_HandleTypeDef UartHandle;
static volatile bool is_tx_done = false;
static volatile bool is_rx_done = false;
static bool is_dma_demo = false;
static uint8_t c_read = 0;

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart == &UartHandle) {
        is_tx_done = true;
    }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart == &UartHandle) {
        if (is_dma_demo) {
            is_rx_done = true;
        } else {
            HAL_UART_Transmit(&UartHandle, &c_read, 1, 0xFFFF);
            HAL_UART_Receive_IT(&UartHandle, &c_read, 1);
        }
    }
}

void sthal_uart_txint_task(void)
{
    uint8_t c = 'a';

    UartHandle.Instance        = (USART_TypeDef *)&vsf_hw_usart1;
    UartHandle.Init.BaudRate   = 115200;
    UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits   = UART_STOPBITS_1;
    UartHandle.Init.Parity     = UART_PARITY_NONE;
    UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
    UartHandle.Init.Mode       = UART_MODE_TX_RX;
    if (HAL_UART_DeInit(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }
    if (HAL_UART_Init(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }

    uint8_t c_read = 0;

    while (1) {
        HAL_UART_Transmit_IT(&UartHandle, &c, 1);
        while (!is_tx_done);

        is_tx_done = false;

        if (c == 'z') {
            c = 'a';
        } else {
            c++;
        }
    }
}

void sthal_uart_rxint_task(void)
{
    uint8_t c = 'a';

    UartHandle.Instance        = (USART_TypeDef *)&vsf_hw_usart1;
    UartHandle.Init.BaudRate   = 115200;
    UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits   = UART_STOPBITS_1;
    UartHandle.Init.Parity     = UART_PARITY_NONE;
    UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
    UartHandle.Init.Mode       = UART_MODE_TX_RX;
    if (HAL_UART_DeInit(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }
    if (HAL_UART_Init(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }


    HAL_UART_Receive_IT(&UartHandle, &c_read, 1);
}

void sthal_uart_echo_task(void)
{
    UartHandle.Instance        = (USART_TypeDef *)&vsf_hw_usart1;
    UartHandle.Init.BaudRate   = 115200;
    UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits   = UART_STOPBITS_1;
    UartHandle.Init.Parity     = UART_PARITY_NONE;
    UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
    UartHandle.Init.Mode       = UART_MODE_TX_RX;
    if (HAL_UART_DeInit(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }
    if (HAL_UART_Init(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }

    uint8_t c_read = 0;
    uint32_t cnt;

    while (1) {
        HAL_StatusTypeDef status = HAL_UART_Receive(&UartHandle, &c_read, 1, 1000);
        if (status == HAL_OK) {
            HAL_UART_Transmit(&UartHandle, &c_read, 1, 0xFFFF);
        } else if (status == HAL_TIMEOUT) {
            printf("HAL_UART_Receive timeout, cnt: %u\n", ++cnt);
        } else {
            printf("HAL_UART_Receive error: %u\n", status);
        }
    }
}

void sthal_uart_dmatx_task(void)
{
    uint8_t outDataab[128];
	for (int i = 0; i < sizeof(outDataab); i++) {
		outDataab[i] = i % 10 + '0';
	}
    
    is_dma_demo = true;
    
    UartHandle.Instance        = (USART_TypeDef *)&vsf_hw_usart1;
    UartHandle.Init.BaudRate   = 115200;
    UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits   = UART_STOPBITS_1;
    UartHandle.Init.Parity     = UART_PARITY_NONE;
    UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
    UartHandle.Init.Mode       = UART_MODE_TX_RX;
    if (HAL_UART_DeInit(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }
    if (HAL_UART_Init(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }

    HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(&UartHandle, outDataab, sizeof(outDataab));
    if (status != HAL_OK) {
        VSF_ASSERT(0);
    }
    
    while (!is_tx_done);
}


void sthal_uart_dmarx_task(void)
{
	uint8_t i;
	uint8_t rx_buf[16];
	for (i = 0; i < sizeof(rx_buf); i++) {
        rx_buf[i] = 0;
	}
    
    is_dma_demo = true;
    
    UartHandle.Instance        = (USART_TypeDef *)&vsf_hw_usart1;
    UartHandle.Init.BaudRate   = 115200;
    UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits   = UART_STOPBITS_1;
    UartHandle.Init.Parity     = UART_PARITY_NONE;
    UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
    UartHandle.Init.Mode       = UART_MODE_TX_RX;
    if (HAL_UART_DeInit(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }
    if (HAL_UART_Init(&UartHandle) != HAL_OK) {
        VSF_ASSERT(0);
    }

    HAL_StatusTypeDef status = HAL_UART_Receive_DMA(&UartHandle, rx_buf, sizeof(rx_buf));
    if (status != HAL_OK) {
        VSF_ASSERT(0);
    }
    
    while (!is_rx_done);
}